//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//

#ifndef BOOST_BEAST_RTSP_IMPL_VERB_IPP
#define BOOST_BEAST_RTSP_IMPL_VERB_IPP

#include <boost/beast/rtsp/verb.hpp>
#include <boost/throw_exception.hpp>
#include <stdexcept>

namespace boost {
namespace beast {
namespace rtsp {

string_view
to_string(verb v)
{
    using namespace beast::detail::string_literals;
    switch(v)
    {
    case verb::describe:            return "DESCRIBE"_sv;
    case verb::announce:            return "ANNOUNCE"_sv;
    case verb::get_parameter:       return "GET_PARAMETER"_sv;
    case verb::play:                return "PLAY"_sv;
    case verb::pause:               return "PAUSE"_sv;
    case verb::record:              return "RECORD"_sv;
    case verb::options:             return "OPTIONS"_sv;
    case verb::redirect:            return "REDIRECT"_sv;

    case verb::setup:               return "SETUP"_sv;
    case verb::set_parameter:       return "SET_PARAMETER"_sv;
    case verb::teardown:            return "TEARDOWN"_sv;

    case verb::unknown:
        return "<unknown>"_sv;
    }

    BOOST_THROW_EXCEPTION(std::invalid_argument{"unknown verb"});
}

verb
string_to_verb(string_view v)
{
/*
    describe
    announce
    get_parameter
    play
    pause
    record
    options
    redirect
    setup
    set_parameter
    teardown
*/
    using namespace beast::detail::string_literals;
    if(v.size() < 3)
        return verb::unknown;
    auto c = v[0];
    v.remove_prefix(1);
    switch(c)
    {
    case 'A':
        if(v == "NNOUNCE"_sv)
            return verb::announce;
        break;

    case 'D':
        if(v == "ESCRIBE"_sv)
            return verb::describe;
        break;

    case 'G':
        if(v == "ET_PARAMETER"_sv)
            return verb::get_parameter;
        break;

    case 'O':
        if(v == "PTIONS"_sv)
            return verb::options;
        break;

    case 'P':
        c = v[0];
        v.remove_prefix(1);
        switch(c)
        {
        case 'A':
            if(v == "USE"_sv)
                return verb::pause;
            break;

        case 'L':
            if(v == "AY"_sv)
                return verb::play;
            break;

        default:
            break;
        }
        break;

    case 'R':
        c = v[0];
        v.remove_prefix(1);
        switch(c)
        {
        case 'E':
            if(v == "CORD"_sv)
                return verb::record;
            if(v == "DIRECT"_sv)
                return verb::redirect;
            BOOST_FALLTHROUGH;
        default:
            break;
        }
        break;

    case 'S':
        c = v[0];
        v.remove_prefix(1);
        switch(c)
        {
        case 'E':
            if(v == "TUP"_sv)
                return verb::setup;
            if(v == "T_PARAMETER"_sv)
                return verb::set_parameter;
            BOOST_FALLTHROUGH;
        default:
            break;
        }
        break;

    case 'T':
        if(v == "TEARDOWN"_sv)
            return verb::teardown;
        break;

    default:
        break;
    }

    return verb::unknown;
}

} // rtsp
} // beast
} // boost

#endif
